#! /usr/bin/env python
"""dialer
"""

from twisted.application import service, internet
from twisted.internet import reactor, protocol, defer, task
from twisted.protocols import basic
from twisted.python import log, logfile, util
from twisted.cred import portal, checkers, credentials

from zope.interface import implements

from starpy import manager, fastagi, utilapplication, menu
import os, logging, pprint, time, sys, threading, binascii
import ConfigParser
from datetime import datetime
from starpyex import asterix

from db_softswitch import db_softswitch

mylog = logging.getLogger('dial_tester')


dialer_config_path = '/etc/emir/dial_tester.ini'


class dial_tester:
    """ """

    def __init__(self):
        """ """

        try:
            self.m_cfgprs = ConfigParser.ConfigParser()
            self.m_cfgprs.read(dialer_config_path)

            print 'reading config file'
            self.log_cfg = {}
            self.log_cfg['log_path'] = self.m_cfgprs.get('log', 'log_path')
            self.log_cfg['open_flags'] = self.m_cfgprs.get('log', 'open_flags')
            self.log_cfg['debug_level'] = self.m_cfgprs.getint('log', 'debug_level')
            print '[log]'
            print 'log_path         = %s' % self.log_cfg['log_path']
            print 'open_flags       = %s' % self.log_cfg['open_flags']
            print 'debug_level      = %s' % self.log_cfg['debug_level']
            log.startLogging(open(self.log_cfg['log_path'], self.log_cfg['open_flags']))

            self.db_softswitch_cfg = {}
            self.db_softswitch_cfg['dbname'] = self.m_cfgprs.get('db_softswitch', 'dbname')
            self.db_softswitch_cfg['user'] = self.m_cfgprs.get('db_softswitch', 'user')
            self.db_softswitch_cfg['host'] = self.m_cfgprs.get('db_softswitch', 'host')
            self.db_softswitch_cfg['password'] = self.m_cfgprs.get('db_softswitch', 'password', True)
            print '[db_softswitch]'
            print 'dbname           = %s' % self.db_softswitch_cfg['dbname']
            print 'user             = %s' % self.db_softswitch_cfg['user']
            print 'host             = %s' % self.db_softswitch_cfg['host']
            print 'password         = %s' % self.db_softswitch_cfg['password']

            self.asterix = {}
            self.asterix['ami_server'] = self.m_cfgprs.get('asterisk', 'ami_server')
            self.asterix['ami_port'] = self.m_cfgprs.getint('asterisk', 'ami_port')
            self.asterix['ami_username'] = self.m_cfgprs.get('asterisk', 'ami_username')
            self.asterix['ami_secret'] = self.m_cfgprs.get('asterisk', 'ami_secret')
            self.asterix['ami_period'] = self.m_cfgprs.getfloat('asterisk', 'ami_period')
            self.asterix['ami_timeout'] = self.m_cfgprs.getfloat('asterisk', 'ami_timeout')
            self.asterix['fagi_interface'] = self.m_cfgprs.get('asterisk', 'fagi_interface')
            self.asterix['fagi_port'] = self.m_cfgprs.getint('asterisk', 'fagi_port')
            self.asterix['log_file'] = self.m_cfgprs.get('asterisk', 'log_file')
            self.asterix['log_tokens'] = self.m_cfgprs.get('asterisk', 'log_tokens')
            self.asterix['log_level'] = self.m_cfgprs.getint('asterisk', 'log_level')
            print '[asterix]'
            print 'ami_server     = %s' % self.asterix['ami_server']
            print 'ami_port       = %s' % self.asterix['ami_port']
            print 'ami_username   = %s' % self.asterix['ami_username']
            print 'ami_secret     = %s' % self.asterix['ami_secret']
            print 'ami_period     = %s' % self.asterix['ami_period']
            print 'ami_timeout    = %s' % self.asterix['ami_timeout']
            print 'fagi_interface = %s' % self.asterix['fagi_interface']
            print 'fagi_port      = %s' % self.asterix['fagi_port']
            print 'log_file       = %s' % self.asterix['log_file']
            print 'log_tokens     = %s' % self.asterix['log_tokens']
            print 'log_level      = %s' % self.asterix['log_level']

            self.softswitch_cfg = {}
            self.softswitch_cfg['host'] = self.m_cfgprs.get('softswitch', 'host')
            print '[softswitch]'
            print 'host           = %s' % self.softswitch_cfg['host']

        except:
            print 'except reading config file'
            pass

        logging.basicConfig()
        mylog.setLevel( self.log_cfg['debug_level'] )

        self.m_asterix = asterix.asterix(ami_username=self.asterix['ami_username'],\
                                         ami_secret=self.asterix['ami_secret'],\
                                         ami_server=self.asterix['ami_server'],\
                                         ami_port=self.asterix['ami_port'],\
                                         ami_connect_handler=self.ami_connect_handler,\
                                         fagi_interface=self.asterix['fagi_interface'],\
                                         fagi_port=self.asterix['fagi_port'],\
                                         fagi_handler=self.fagi_handler,\
                                         fagi_vars=['calleddtmf'],\
                                         log_file=self.asterix['log_file'],\
                                         log_tokens=self.asterix['log_tokens'],\
                                         log_level=self.asterix['log_level'])

        dsn = "dbname=%(dbname)s user=%(user)s host=%(host)s password=%(password)s" % self.db_softswitch_cfg
        self.db_softswitch = db_softswitch(dsn=dsn, test_period=5.0)
        self.testphones = self.db_softswitch.select_testphones(trunktype='sip')
        print 'testphones: %s' % self.testphones
        self.testextens = self.db_softswitch.select_testextens()
        print 'testextens: %s' % self.testextens
        self.dials = {}
        self.answerdials = []
        self.successdials = {}
    
    def testresults(self, start):
        finish = datetime.now()
        self.db_softswitch.update_testresults(start=start, finish=finish, call_amount=len(self.dials), answer_amount=len(self.answerdials), success_amount=len(self.successdials))
        reactor.stop()

    def testdials(self):
        for call in range(1):
            self.makecall()

    def makecall(self):
        for phone in self.testphones:
            callparam = {}
            if not self.testextens:
                break
            exten = self.testextens.pop(0)
            callparam['type'] = phone['type']
            callparam['identifier'] = '%s@%s' % (exten, self.softswitch_cfg['host'])
            #callparam['identifier'] = '%s/%s' % (phone['callerid'], exten)
            callparam['callerid'] = phone['callerid']
            print 'callparam: %s' % callparam
            self.testextens.append(exten)
            print 'testextens: %s' % self.testextens
            #reactor.callLater(1.0, self.originate, callparam)
            self.originate(callparam)
            self.dials[phone['callerid']] = phone['callerid']


    def ami_connect_handler(self):
        """ ami_connect_handler """
        print 'ami_connect_handler'
        reactor.callLater(3.0, self.testdials)
        start = datetime.now()
        reactor.callLater(30.0, self.testresults, start)

    def fagi_handler(self, agi):
        """ fagi_handler """
        mylog.debug('fagi_handler()')

        def onReadVal(val):
            print 'onReadVal %s' % val
        def ReadVal():
            #df = agi.Read(timeout=5,option='noanswer')
            df = agi.Read(timeout=10)
            df.addCallback(onReadVal)
        #ReadVal()
        print 'calleddtmf %s' % agi.variables['calleddtmf']
        self.db_softswitch.update_testdials(status=agi.variables['calleddtmf'])
        self.answerdials.append(agi.variables['calleddtmf'])
        return {}

    def originate(self, callparam):
        """ originate() """
        print 'originate (%s)' % (callparam)

        def onOriginateOk(result, callparam):
            """  """
            print 'originate (%s) ok %s' % (callparam, result)
        def onOriginateErr(reason, callparam):
            """  """
            print 'originate (%s) err %s' % (callparam, reason)
        df = self.m_asterix.m_ami.originate('%s/%s' % (callparam['type'], callparam['identifier']),
                                            'test',
                                            123,
                                            1,
                                            30,
                                            callparam['callerid'],
                                            None,
                                            None,
                                            None,
                                            {'callerdtmf': callparam['callerid']},
                                            True )
        df.addCallbacks(onOriginateOk, onOriginateErr, callbackArgs=(callparam,), errbackArgs=(callparam,))


if __name__ == "__main__":
    dial_tester = dial_tester()
    reactor.run()
